// SyntaxAnalysis.h

#include "../headers/SyntaxAnalysis.h"
#include <sstream>

using namespace std;


string SyntaxAnalysis::Translate(string t){
	string r;
	char *p;
	p=const_cast<char*>(t.c_str());	

	switch(p[0])
	{
	case '<':
		if(_bLeftEnd){
			_ptrCount += 1 ;
			_currentPos = 0;
			_countLeft++;
			_bRightEnd = false;
		}else{
			_currentPos -= 1;
			if (_currentPos == 0){ _bLeftEnd = true;}
		}
		if(_countera!=0) {
			stringstream s;
			s << _countera;	
			r=" "+s.str()+"\nMOVE_LEFT";
			_countera=0;
			_counterpg++;

		}else if(_counters!=0){
			stringstream s;
			s << _counters;	
			r=" "+s.str()+"\nMOVE_LEFT";
			_counters=0;
			_counterpg++;
		}else if(_counterpg!=0){
			_counterpg++;
		}else if(_counterpd!=0){
			stringstream s;
			s << _counterpd;	
			r=" "+s.str()+"\nMOVE_LEFT";
			_counterpd=0;
			_counterpg++;
		}else{
			r="\nMOVE_LEFT";
			_counterpg++;
		}
		break;
	case '>':
		if(_bRightEnd){
			_ptrCount += 1 ;
			_currentPos = _ptrCount -1;
			_bLeftEnd = false;
		}else{
			_currentPos += 1;
			if (_currentPos == _ptrCount - 1) { _bRightEnd= true;}
		}
		if(_countera!=0){
			stringstream s;
			s << _countera;	
			r=" "+s.str()+"\nMOVE_RIGHT";
			_counterpd++;
			_countera=0;
		}else if(_counters!=0){
			stringstream s;
			s << _counters;	
			r=" "+s.str()+"\nMOVE_RIGHT";
			_counterpd++;
			_counters=0;
		}else if(_counterpg!=0){
			stringstream s;
			s << _counterpg;	
			r=" "+s.str()+"\nMOVE_RIGHT";
			_counterpg=0;
			_counterpd++;
		}else if(_counterpd!=0){
			_counterpd++;
		}else{
			r="\nMOVE_RIGHT";
			_counterpd++;
		}
		break;
	case '+':
		if(_countera!=0)
		{
			_countera++;
		}else if(_counters!=0){
			stringstream s;
			s << _counters;	
			r=" "+s.str()+"\nADD";
			_counters=0;
			_countera++;
		}else if(_counterpg!=0){
			stringstream s;
			s << _counterpg;	
			r=" "+s.str()+"\nADD";
			_counterpg=0;		
			_countera++;
		}else if(_counterpd!=0){
			stringstream s;
			s << _counterpd;	
			r=" "+s.str()+"\nADD";
			_counterpd=0;
			_countera++;
		}else{
			r="\nADD";
			_countera++;
		}
		break;
	case '-':
		if(_countera!=0)
		{
			stringstream s;
			s << _countera;	
			r=" "+s.str()+"\nSUB";
			_countera=0;
			_counters++;
		}else if(_counters!=0){
			_counters++;
		}else if(_counterpg!=0){
			stringstream s;
			s << _counterpg;	
			r=" "+s.str()+"\nSUB";
			_counters++;
			_counterpg=0;
		}else if(_counterpd!=0){
			stringstream s;
			s << _counterpd;	
			r=" "+s.str()+"\nSUB";
			_counterpd=0;
			_counters++;
		}else{
			r="\nSUB";
			_counters++;
		}
		break;
	case '[':
		_num_loop+=1;
		if(_countera!=0)
		{
			stringstream s;
			s << _countera;	
			r=" "+s.str()+"\nSTART_LOOP";
			_countera=0;
		}else if(_counters!=0){
			stringstream s;
			s << _counters;	
			r=" "+s.str()+"\nSTART_LOOP";
			_counters=0;
		}else if(_counterpg!=0){
			stringstream s;
			s << _counterpg;	
			r=" "+s.str()+"\nSTART_LOOP";
			_counterpg=0;
		}else if(_counterpd!=0){
			stringstream s;
			s << _counterpd;	
			r=" "+s.str()+"\nSTART_LOOP";
			_counterpd=0;
		}else{
			r="\nSTART_LOOP";
		}
		break;
	case ']':
		_num_loop-=1;
		if(_countera!=0)
		{
			stringstream s;
			s << _countera;	
			r=" "+s.str()+"\nEND_LOOP";
			_countera=0;
		} else if(_counters!=0){
			stringstream s;
			s << _counters;	
			r=" "+s.str()+"\nEND_LOOP";
			_counters=0;
		}else if(_counterpg!=0){
			stringstream s;
			s << _counterpg;	
			r=" "+s.str()+"\nEND_LOOP";
			_counterpg=0;
		}else if(_counterpd!=0){
			stringstream s;
			s << _counterpd;	
			r=" "+s.str()+"\nEND_LOOP";
			_counterpd=0;
		}else{
			r="\nEND_LOOP";
		}
		break;
	case '.':
		if(_countera!=0)
		{
			stringstream s;
			s << _countera;	
			r=" "+s.str()+"\nSHOW";
			_countera=0;
		}else if(_counters!=0){
			stringstream s;
			s << _counters;	
			r=" "+s.str()+"\nSHOW";
			_counters=0;
		}else if(_counterpg!=0){
			stringstream s;
			s << _counterpg;	
			r=" "+s.str()+"\nSHOW";
			_counterpg=0;
		}else if(_counterpd!=0){
			stringstream s;
			s << _counterpd;	
			r=" "+s.str()+"\nSHOW";
			_counterpd=0;
		}else{
			r="\nSHOW";
		}
		break;
	case ',':
		if(_countera!=0)
		{
			stringstream s;
			s << _countera;	
			r=" "+s.str()+"\nGET";
			_countera=0;
		}else if(_counters!=0){
			stringstream s;
			s << _counters;	
			r=" "+s.str()+"\nGET";
			_counters=0;
		}else if(_counterpg!=0){
			stringstream s;
			s << _counterpg;	
			r=" "+s.str()+"\nGET";
			_counterpg=0;
		}else if(_counterpd!=0){
			stringstream s;
			s << _counterpd;	
			r=" "+s.str()+"\nGET";
			_counterpd=0;
		}else{
			r="\nGET";
		}
		break;
	default:
		r="";
	}
	if (_BOF) { //if beginning of file
		r = r.substr(1); // only take the first character
	}
	return r;	
}

void SyntaxAnalysis::Process(Data<ifstream>& objInput, Data<ofstream>& objOutput)
{		
	//initialisation
	while(!objInput.Test_EOF()) //lecture des caractere jusqu'a End Of File	
	{
		_sTmp = objInput.Get_char();//renvoie caractere
		cout << _sTmp;
		string t = Translate(_sTmp);
		objOutput.Write(t);
		if (_BOF) { //Teste le début du fichier
			_BOF = false;
		}
	}
	objOutput.Write("\ntest_end");
	//check for non closing loop
	if(_num_loop!=0){
		cout << "\n\n Warning!!:non closing loops";
		int foo;
		cin >> foo;	
	}
	_ptrCount--;
}
int SyntaxAnalysis::Get_countLeft(void){

	return _countLeft;

}
int SyntaxAnalysis::Get_ptrCount(void){
		return _ptrCount;
}

//SyntaxAnalysis *SyntaxAnalysis::_singleton = NULL;
